// JavaScript Document
//createBy kuoqi
"use strict";
((function(w){
	
	
	
	//基础的包信息
	var a = function(){};
	
	//
	var b = function(){
		
	}
	
	//ready的基础信息
	//执行代码 doReady();
	var c = function(func){
		if(typeof(func)=='function'){
			//存储准备数据信息们
			d.readlist.push(func);
		}else{
			//执行func的数据信息
			((function(ths){
				ths.Debug('调用用户自定义[function:app.ready]');
				d.readlist.forEach(function(e){
					ths._callback  = e;
					ths._callback();
				});
			})(this))
		}
	}
	
	//数据相关存储模块
	var d = {
		readlist:[],//准备数据列表信息	
		models:{},//model的列表，使用hash
		resources:{},//资源清单，键值对
		pages:{},//页面列表信息，键值为路由信息
		config:{
			models:[],
			resource:[],
		},//配置列表基础信息
		configPath:'',//配置的外部加载路径信息，如果有这个值，初始化的时候需要初始化这个值进行路径获取
		cbktmps:[],//获取返回缓存ID的地方
		now:null,//当前使用的页面对象，标记为对象信息
		//默认加载的系统路由信息们
		init_models:[
			'./library/config.js',//加载器信息加载
			'./library/resource.js',//加载资源对象相关模块
			'./library/app.js',//app的基础模块,预定义app的相关信息
			'./library/tools.js',//加载一些基础的函数,工具函数
		],
	};
	
	//基础配置函数
	//init
	var e = function(cfgs){
		
		//执行初始化的参数操作
		this.Debug('==调用用户配置[function:app.init]==');
		for(var i in cfgs){
			d.config[i] = cfgs[i];
		}
		
		//执行初始化的程序操作
		this.initialize(function(){
			//初始化完成，进行用户ready操作，这里可以嵌入系统想放置的内容
			this.ready();	
		});
	};
	
	//系统debug信息
	var f = function(devmsg){
		this.debug&&console.warn(devmsg);
	}
	
	//程序初始化执行的操作们，，，，巴拉巴拉
	var g = function(callback){
		
		//整合已有的models
		//判定有没有系统初始化的配置路径信息，
		var ths = this;
		ths.Debug('系统开始初始化');
		var g_c = function(){
			ths.Debug('系统初始化成功，等待初始化应用模块信息');
			//系统初始化完成之后执行一遍model规整
			ths.syncModels();
			ths._callback = callback;
			ths._callback();	
		}
		
		//初始化配置的相关数据信息
		var g_b = function(){
			
			//models加载	
			//ths.library.config.models
			ths.loadall(ths.library.config.models,function(){
				//加载资源清单信息信息
				this.loadreslist(ths.library.config.resource,function(){
					g_c();
				});
				
			});
		}
		
		var g_a = function(){
			if(d.configPath){
				ths.Debug('拥有系统配置，进行系统配置加载');	
				ths.loader(d.configPath,function(){
					//加载返回之后出现的系统信息
					//尝试进行模型的初始化操作
					//这个过程不包含加载文件的流程，所以 不需要进行返回即可配置
					ths.syncModels();
					//这里要解析config配置文件的相关参数信息，加入到对应的信息中
					
					//判定是否有模型文件
					if(ths.config){
						
						//配置models的相关信息
						ths.config.models.forEach(function(d){
							ths.library.config.models.push(d);	
						});
						
						//配置资源的相关信息
						ths.config.resource.forEach(function(d){
							ths.library.config.resource.push(d);	
						});
						
						g_b();
						
					}else{
						//这种情况是直接返回	
						g_b();
					}
					
				});
			}else{
				ths.Debug('未找到系统配置，可使用[function:app.useConfig]进行配置使用');
				//判定是否有配置文件
				ths.Debug('系统初始化完成');
				g_b();
			}
				
		};
		
		
		//初始化查看系统中是否有数据信息需要加载，如果有先加载系统核心组键
		if(d.init_models){
			//加载系统的js列表信息们
			this.loadall(d.init_models,function(){
				g_a(this);
			},true);
		}else{
			g_a(this);	
		}
	}
	
	//引入配置文件的参数
	var h = function(cfgpath){
		this.Debug('引入外部配置文件');
		d.configPath = cfgpath;
	}
	
	//获取一个临时的callback值，不重复但是可以使用的那种
	//getTmpcbkid
	var i = function(){
		return '_callback_'+parseInt(Math.random() * 10000);
	}
	
	//定义一个系统操作对象方法
	var j = function(modelID,modelConts){
		var ths = this;
		//将一个模型写入到模型库中[需要传入[modelID,model]]
		var model = new function Kmodel(){
			this.route = modelID;//这个为唯一路由
			for(var i in modelConts){
				this[i] = modelConts[i];
			}
			
			//这个模型是否已经初始化继承相关信息，这个设置为默认值而不是继承值
			this.isExtend = false;
			//这个模型是否已经初始化，这个设置为默认值而不是继承值
			this.hasInit = false;
			
			this.isModule = false;//是否已经执行module初始化
			
			//当前模型是否调试中，给一个调试属性
			if(this.debug==undefined){
				this.debug = false;	
			}
						
			this.__LOAD_STATE = 0;//状态值[0:待加载，1:加载成功]
			this.__STATE_OK = 1;//加载完成的状态
			
			this.__proto__ = o_a.model;
			this.top = ths;
			this.new = o_a.new;//配置方法信息
		}
		return d.models[modelID] =  model;
	}
	
	//模型的初始化操作
	//syncModels
	var k = function(){
		//尝试模型的初始化
		var mods = d.models;
		for(i in mods){
			//_models[i] = mods[i].new();这个会初始化一个？不不不，，这里不要重新初始化，如果重新初始化会重复调用
			
			//如果没有extend化则执行
			if(!mods[i].isExtend){
				if(mods[i].extends){
					mods[i] = this.extend(mods[i].extends,mods[i]);
				}
			}
			
			//执行models相关信息
			//进行模型归档
			//如果没有module化，则执行
			if((!mods[i].isModule)&&mods[i].__toModule){
				mods[i].__toModule();//归档进入池子
				mods[i].isModule = true;
			}
			
			//_models[i]._to&&_models[i].init();
			//_models[i].init&&_models[i].init();
		}	
	}
	
	
	//一些公共方法合集
	var o_a = {
		model:{},
		new:function(cfgs,defgs){ 
			var ths = this;
			return new function 
				Kmodel(){
					for(var i in cfgs){
						this[i] = cfgs[i];
					}
					this.__proto__ = ths;
					return this;	
				}
		}
	};
	
	//loader的核心加载程序
	//第一个参数为加载的包，第二个程序为加载的返回，第三个参数为系统加载还是程序加载，系统加载为加载系统模块的内容区域，程序加载未加载程序模块的内容信息，有什么区别呢，第一个为ROOT,第二个为APP_ROOT
	var l = function(f,callback,isRoot){
		var t = typeof(f);
		var file = '';
		(isRoot==undefined)&&(isRoot = false);
		file = this.any2path(f,isRoot);
		/*if(t=='string'){
			file = isRoot?this.root+f:this.home+f;
		}else if(t=='undefined'){
			return this.Debug('加载外部文件:'+JSON.stringify(f)+'失败，请检查');
		}else{
			//判定如果是一个字符串
			console.log(typeof(f));
			return this.Debug('暂不支持加载外部文件:'+JSON.stringify(f)+'请检查');
		}*/
		
		var cbkid = this.getTmpcbkid();
		this[cbkid] = callback;
		var ths = this;
		//this[this.getTmpcbkid()]
		//loader加载程序
		//加载文件专用
		var script = window.document.createElement("script");
		script.type = 'text/javascript';
		if(this.version){
			script.src = file+'?v='+this.version;
		}else{
			script.src = file;
		}
		
		script.onload = script.onreadystatechange = function() {
			if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete" ) {
				ths[cbkid](true);
				script.onload = script.onreadystatechange = null;
			}
		};
		script.onerror = function(){
			ths[cbkid](false);
		}
		window.document.getElementsByTagName("head").item(0).appendChild(script);	
			
	}
	
	//加载js列表的操作的那种
	var lall = function(files,callback,isRoot){
		var ths = this;
		var i = 0;
		var a = function(){
			if(files[i]){
				ths.loader(files[i],function(){
					i++;
					a();
				},isRoot);	
			}else{
				//加载完成时候执行
				var cbid = ths.getTmpcbkid();
				ths[cbid] = callback;
				ths[cbid]();
			}
		}
		a();
	}
	
	//extend
	var m = function(route,obj){
		obj.extends = route;
		var ext = d.models[route]?d.models[route]:null;
		if(ext){
			obj.isExtend = true;
			for(var i in ext){
				if(obj[i]==undefined){
					obj[i] = ext[i];
				}
			}
			obj[i].init&&obj[i].init();
		}else{
			this.Debug('route ['+route+'] non-exists');
			obj.isExtend = false;
		}
		return obj;
	}
	
	//加载资源信息
	var n = function(path,call){
		//尝试加载资源信息，当然这个是可以使用缓存的方式加入的
		path = this.any2path(path);
		var proxy = $Q.proxy({
			action:path,
			dataType:'blob',
			responseType:'blob',
			success:function(rs){
				call(rs);	
			},
			error:function(){
				call('');	
			}
		});
		proxy.send();	
	}
	
	//加载资源列表
	var nall = function(files,callback,isRoot){
		var ths = this;
		var i = 0;
		var a = function(){
			if(files[i]){
				ths.loadres(files[i],function(rs){
					//将资源信息写入到资源列表中
					ths.getModel('Kuoqi.resource').new({
						blob:rs,
						name:files[i].name
					}).init();
					//这里是继续执行
					i++;
					a();
				},isRoot);	
			}else{
				//加载完成时候执行
				var cbid = ths.getTmpcbkid();
				ths[cbid] = callback;
				ths[cbid]();
			}
		}
		a();	
	}
	
	//获取模型
	var o = function(mdname){
		if(this.library.models[mdname]){
			return this.library.models[mdname];	
		}else{
			this.Debug('模型'+mdname+'不可被引用，不存在');	
		}
	}
	
	//运行一个路由信息
	//app.run
	var p = function(route){
		//第一步获取路由，分为两种情况，分别为路由存在和路由不存在的情况
		this.getPage(route,function(){});//尝试获取页面信息
		
	}
	
	//简单算法，根据输入的对象信息将path转换为加载的路径的信息
	var any2path = function(ipt,isRoot){
		if(typeof(ipt)=='object'){
			if(ipt.isRoot){
				isRoot = ipt.isRoot;	
			}
			//如果判定url存在，则直接返回url
			if(ipt.url){
				return ipt.url;	
			}else if(ipt.path){
				return isRoot?this.root+ipt.path:this.home+ipt.path;	
			}else{
				this.Debug('error');	
				console.log(ipt);	
			}
		}else{
			
			return isRoot?this.root+ipt:this.home+ipt;
		}
	}
	
	//基础的包信息
	var KuoqiAppjs = function(){
		
		
		//是否测试版
		this.debug = true;
		
		//版本号信息
		this.version = '1.00.00';
		
		//系统根目录
		this.root = ((function(){
			var path = document.scripts;
				path = path[path.length - 1].src.substring(0, path[path.length - 1].src.lastIndexOf("/") + 1)
			return path;
		})());
		
		//应用根目录
		this.home = '';
		
		//系统debug信息
		this.Debug = f;
		
		//基础准备信息
		this.ready = c;
		
		//基础库信息
		this.library = d;
		
		//基础配置的列表信息
		this.init = e;
		
		//加载程序的核心加载
		this.loader = l;
		this.loadall = lall;
		
		//配置信息,完成时候执行信息
		
		//实际完成加载内容的信息
		this.initialize = g;
		
		//引入外部配置文件
		this.useConfig = h;
		
		//获取一个临时的缓存callbackID
		this.getTmpcbkid = i;
		
		//定义一个系统模型的操作方法
		this.define = j;
		
		
		//模型的初始化操作
		this.syncModels = k;
		
		//extend
		this.extend = m;
		
		//加载资源
		this.loadres = n;
		this.loadreslist = nall;
		
		//简单的路径变更器
		this.any2path = any2path;
		
		//获取模型
		this.getModel = o;
		
		//运行自定义路由
		this.run = p;
		
		//this.ready();
		
	}
	
	//基础的Kapp的内容区域
	w.Kapp = w.KuoqiAppjs = new KuoqiAppjs();
})(this));